//
// Created by Administrator on 2021/5/3.
//
/*

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。


示例 1：


输入：l1 = [1,2,4], l2 = [1,3,4]
输出：[1,1,2,3,4,4]
示例 2：

输入：l1 = [], l2 = []
输出：[]
示例 3：

输入：l1 = [], l2 = [0]
输出：[0]


提示：

两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/merge-two-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*/
#include <iostream>

//Definition for singly-linked list.
struct ListNode {
    int val;
    ListNode *next;

    ListNode() : val(0), next(nullptr) {}

    ListNode(int x) : val(x), next(nullptr) {}

    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        // 递归
        if (l1 == nullptr) return l2;
        else if (l2 == nullptr) return l1;
        else if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1; // 把这个节点返回
        } else {
            l2->next = mergeTwoLists(l1, l2->next);
            return l2;
        }
    }

};

class Solution2 {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        // 迭代
        auto *preHead = new ListNode(-1); // 什么时候delete？

        ListNode *prev = preHead;
        while (l1 != nullptr && l2 != nullptr) {
            if (l1->val < l2->val) {
                prev->next = l1;
                l1 = l1->next;
            } else {
                prev->next = l2;
                l2 = l2->next;
            }
            prev = prev->next;
        }

        // 合并后 l1 和 l2 最多只有一个还未被合并完，我们直接将链表末尾指向未合并完的链表即可
        prev->next = l1 == nullptr ? l2 : l1;

        return preHead->next;
    }
};

void printList(ListNode *node) {
    auto firstNode = node;
    do {
        std::cout << firstNode->val << std::endl;
        firstNode = firstNode->next;
    } while (firstNode != nullptr);
}

int main() {
    auto n3 = ListNode(4);
    auto n2 = ListNode(2, &n3);
    auto n1 = ListNode(1, &n2);

    auto l3 = ListNode(4);
    auto l2 = ListNode(3, &l3);
    auto l1 = ListNode(1, &l2);

    Solution sol;
    printList(sol.mergeTwoLists(&n1, &l1));
    return 0;
}